import yaml
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.chrome.webdriver import WebDriver

from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait


class BaseDriver:
    def __init__(self, driver: WebDriver = None):
        if driver is None:
            # 实例化driver
            self.driver = webdriver.Chrome()
            with open("D:/Study/git/WeComWebTest/data/cookies.yaml", encoding="utf-8") as f:
                cookies = yaml.safe_load(f)

            # 设置隐式等待
            self.driver.implicitly_wait(10)
            # 打开网页
            self.driver.get('https://work.weixin.qq.com/wework_admin/frame')

            # 添加cookies
            for cookie in cookies:
                self.driver.add_cookie(cookie)
            # 刷新页面
            self.driver.get('https://work.weixin.qq.com/wework_admin/frame')

        else:
            self.driver = driver

    def find_and_click(self, by, value=None):
        # 传元组或分开都可以
        # 定位元素并点击
        if isinstance(by, tuple):
            return self.driver.find_element(*by).click()
        else:
            return self.driver.find_element(by, value).click()

    def find_and_input(self, by, value, text: str):
        # 定位元素并输入内容
        ele = self.driver.find_element(by, value)
        ele.send_keys(text)

    def find_ele(self, by, value):
        # 定位元素
        return self.driver.find_element(by, value)

    def find_eles(self, by, value=None):
        # 定位多个元素
        if isinstance(by, tuple):
            return self.driver.find_elements(*by)
        else:
            return self.driver.find_elements(by, value)

    def get_ele_test(self, by, value):
        # 定位元素返回其文本
        return self.find_ele(by, value).text

    def close(self):
        # 封装起来，外部可调用
        self.driver.quit()

    def back(self):
        # 封装起来，外部可调用
        self.driver.back()

    def wait_elements(self, locator, time=10):
        # 显式等待封装 传入元组 默认等待时间10秒
        elements = WebDriverWait(self.driver, time).until(
            expected_conditions.visibility_of_all_elements_located(locator))
        return elements

    def loop_click(self, click_element, wait_element, click_num=500):
        # 计数器 点击次数超出设置值 抛出异常
        num = 0
        # 设置死循环 循环跳出条件为 找到预期元素 或 抛出异常
        while True:
            # 判断次数是否超出
            if num >= click_num:
                raise NoSuchElementException
            # 判断是否找到预期元素 这里利用了elements找不到不报错返回空列表的特性 长度大于0 即有内容
            if len(self.find_eles(wait_element)) >= 1:
                break

            # 点击按钮
            self.find_and_click(click_element)
            # 点击计数+1
            num += 1
